// Copyright (C) 2023 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
// 
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<北京小羊驼科技有限公司>，授权编号：<NT231212144350>，代码指纹：<A.702363430.550>，技术对接人微信：<ID: wxid_wbyootvkdcgj22>】
// 【授权寄送：<收件：苏先生、地址：北京市大兴区北京密码西区6号楼1单元301、电话：18613885610、邮箱：bd@huiyuanxiang-inc.com>】
// 
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
// 
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.rbchat.network.http.bigfile;
import android.content.Context;
import android.util.Log;

import com.eva.android.HttpService4A;
import com.eva.android.HttpsUtils;
import com.eva.android.OkHttpsUtils;
import com.x52im.rbchat.MyApplication;

import java.util.HashMap;
import java.util.Map;
import java.util.Observer;
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Future;  
import java.util.concurrent.TimeUnit;  
  
import okhttp3.OkHttpClient;  
  
/** 
 * 上传管理器 
 * 
 * @author wangjian
 */  
public class BigFileUploadManager
{
    private static Context mContext;  
    
    private OkHttpClient mClient;  
  
    private int mPoolSize = 20;  
    
    // 将执行结果保存在future变量中  
    private Map<String, Future> mFutureMap;  
    private ExecutorService mExecutor;  
    private Map<String, BigFileUploadTask> mCurrentTaskList;  
    
    /** 
     * 文件任务状态改变观察者，用于UI及时刷新文件上传状态在界面上的显示（每种
     * 需要支持大文件消息的聊天界面，都应该设置或取消设置本观察者）。 */
    private Observer fileStatusChangedObserver = null;

    public BigFileUploadManager(Context context) 
    {  
        this.mContext = context;
        
        initOkhttpClient();  
  
        // 初始化线程池  
        mExecutor = Executors.newFixedThreadPool(mPoolSize);  
        mFutureMap = new HashMap<String, Future>();  
        mCurrentTaskList = new HashMap<String, BigFileUploadTask>();  
    }

    private OkHttpClient createOkHttpClient(boolean isHttps)
    {
        //** 设置超时时间及缓存
        OkHttpClient.Builder okBuilder = new OkHttpClient.Builder();
        okBuilder.connectTimeout(1000, TimeUnit.SECONDS);
        okBuilder.readTimeout(1000, TimeUnit.SECONDS);
        okBuilder.writeTimeout(1000, TimeUnit.SECONDS);

        // 如果是https则需要进行ssl相关的配置设置
        if(isHttps) {
            Log.i(BigFileUploadManager.class.getSimpleName(), "【HTTPS】将为此大文件上传启用https设置。。。");
            OkHttpsUtils httpsUtils = OkHttpsUtils.getInstance(MyApplication.getInstance2());
            okBuilder.hostnameVerifier(httpsUtils.getHostnameVerifier());
            okBuilder.sslSocketFactory(httpsUtils.getSslSocketFactory(), httpsUtils.getTrustManager());
        }

        return okBuilder.build();
    }

    /**
     * 初始化okhttp
     */
    private void initOkhttpClient()
    {
        mClient = createOkHttpClient(false);
    }

    /**
     * 添加上传任务
     *
     * @param uploadTask
     */
    public void addUploadTask(BigFileUploadTask uploadTask)
    {
        if (uploadTask != null && !isUploading(uploadTask))
        {
            // 文件上传服务url是否是https
            boolean isHttps = HttpsUtils.isHttps(uploadTask.getUrl());
            uploadTask.setClient(isHttps? createOkHttpClient(true) : mClient);
            uploadTask.setUploadStatus(BigFileUploadTask.UPLOAD_STATUS_INIT);
            // 保存上传task列表  
            mCurrentTaskList.put(uploadTask.getId(), uploadTask);
            Future future = mExecutor.submit(uploadTask);
            mFutureMap.put(uploadTask.getId(), future);
        }
    }

    private boolean isUploading(BigFileUploadTask task)
    {
        if (task != null)
        {
            if (task.getUploadStatus() == BigFileUploadTask.UPLOAD_STATUS_UPLOADING)
            {
                return true;
            }
        }
        return false;
    }

    public boolean isUploading(String id)
    {
        return isUploading(getUploadTask(id));
    }

    /**
     * 暂停上传任务
     *
     * @param id 任务id
     */
    public void pause(String id)
    {
        BigFileUploadTask task = getUploadTask(id);
        if (task != null)
        {
            task.setUploadStatus(BigFileUploadTask.UPLOAD_STATUS_PAUSE);
        }
    }

    /**
     * 重新开始已经暂停的上传任务
     *
     * @param id 任务id
     */
    public void resume(String id)
    {
        BigFileUploadTask task = getUploadTask(id);
        if (task != null)
        {
            addUploadTask(task);
        }
    }  
  
    /** 
     * 取消上传任务(同时会删除已经上传的文件，和清空数据库缓存) 
     * 
     * @param id       任务id 
     * @param listener 
     *//* 
    public void cancel(String id, BigFileUploadTaskListener listener) { 
        BigFileUploadTask task = getUploadTask(id); 
        if (task != null) { 
            mCurrentTaskList.remove(id); 
            mFutureMap.remove(id); 
            task.setmListener(listener); 
            task.cancel(); 
            task.setDownloadStatus(UploadStatus.DOWNLOAD_STATUS_CANCEL); 
        } 
    }*/

    /**
     * 实时更新manager中的task信息
     *
     * @param task
     */
    public void updateUploadTask(BigFileUploadTask task)
    {
        if (task != null)
        {
            BigFileUploadTask currTask = getUploadTask(task.getId());
            if (currTask != null)
            {
                mCurrentTaskList.put(task.getId(), task);
            }
        }
    }

    /**
     * 获得指定的task
     *
     * @param id task id
     * @return
     */
    public BigFileUploadTask getUploadTask(String id)
    {
        BigFileUploadTask currTask = mCurrentTaskList.get(id);
        if (currTask == null)
        {
            currTask = parseEntity2Task(new BigFileUploadTask.Builder().build());
            // 放入task list中  
            mCurrentTaskList.put(id, currTask);
        }

        return currTask;
    }
  
    private BigFileUploadTask parseEntity2Task(BigFileUploadTask currTask) {  
  
        BigFileUploadTask.Builder builder = new BigFileUploadTask.Builder()//  
                .setUploadStatus(currTask.getUploadStatus())  
                .setFileName(currTask.getFileName())//  
                .setUrl(currTask.getUrl())  
                .setId(currTask.getId());  
  
            currTask.setBuilder(builder);  
  
        return currTask;  
    }

    public void setFileStatusChangedObserver(Observer fileStatusChangedObserver)
    {
        this.fileStatusChangedObserver = fileStatusChangedObserver;
    }

    public Observer getFileStatusChangedObserver()
    {
        return fileStatusChangedObserver;
    }
} 